package cn.ad.server.persistence;

import cn.ad.server.domain.ad.AmountStore;
import cn.ad.server.domain.ad.Campaign;
import cn.ad.server.persistence.dao.CampaignDao;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.*;

@Repository
public class CampaignRepositoryImpl implements CampaignRepository {
	
	Map<Integer,Campaign> cache = new HashMap<Integer,Campaign>();
	Map<String, Long> timeCache = new HashMap<String, Long>();
	
	@Resource(name = "cacheRedisTemplate")
	private ValueOperations<String, Double> countOperations;

	@Resource(name = "cacheRedisTemplate")
	private ValueOperations<String, Campaign> campaignValueOperations;
	
	//@Autowired
	private CampaignDao campaignDao;

	@Override
	public List<AmountStore> findAmounts(Campaign c) {
		List<String> keys = new ArrayList<String>();
		keys.add(c.maxClicksKey());
		keys.add(c.dayClicksKey());
		keys.add(c.maxImpressionsKey());
		keys.add(c.dayImpressionsKey());
		keys.add(c.maxBudgetKey());
		keys.add(c.dayBudgetKey());

		List<Double> amounts = this.countOperations.multiGet(keys);
		List<AmountStore> result = new ArrayList<AmountStore>();
		if (CollectionUtils.isEmpty(amounts))
			return result;

		for (int i = 0; i < keys.size(); i++) {
			Number n = amounts.get(i);
			if (n != null) {
				AmountStore as = new AmountStore();
				as.setObjectType(2);
				as.setObjectId(c.getId());
				as.setCacheKey(keys.get(i));
				as.setAmount(n.doubleValue());
				as.setAmountType(i + 1);
				result.add(as);
			}
		}

		return result;
	}

	@Override
	public List<Campaign> findAvailable() {
		return campaignDao.findAvailable();
	}

	
	public Campaign fetchCampaignById(Integer campaignId) {
		//return campaignValueOperations.get(Campaign.cacheKey(campaignId));
		return fetch(campaignId);
	}
	
	
	Campaign fetch(int cid) {
		String lastTimeKey = String.valueOf(cid) + ".time";
		long lastTimeValue = timeCache.get(lastTimeKey) == null ? 0 : timeCache.get(lastTimeKey);
		Campaign value = cache.get(cid);
		long mDiff = (System.currentTimeMillis() - lastTimeValue) / 1000;
		if (value == null || mDiff >= 30) {
			value = campaignValueOperations.get(Campaign.cacheKey(cid));
			cache.put(cid, value);
			timeCache.put(lastTimeKey, System.currentTimeMillis());
		}
		return value;
	}
	
	
	public List<Campaign> multiFetchCampaignByIds(Collection<String> campaignIds) {
		return campaignValueOperations.multiGet(campaignIds);
	}


}
